#include <string>
#include <vector>
#include <algorithm>
using namespace std;
/*
 * @lc app=leetcode.cn id=132 lang=cpp
 *
 * [132] 分割回文串 II
 */

// @lc code=start
class Solution {
public:
    // int minCut(string s) {
    //     vector<vector<bool>> is_prime(s.length(), vector<bool>(s.length(), true));
    //     // is_prime[i][j] = is_prime[i + 1][j - 1] && 
    //     int sz = s.size();
    //     for (int i = sz - 1; i >= 0; i--) {
    //         for (int j = i + 1; j < sz; j++) {
    //             is_prime[i][j] = is_prime[i + 1][j - 1] && (s[i] == s[j]);
    //         }
    //     }
    //     vector<vector<int>> dp(sz, vector<int>(sz, INT_MAX));
    //     return rect(0, sz - 1, is_prime, dp);
    // }

    // int rect(int s, int e, vector<vector<bool>> & is_prime, vector<vector<int>> &dp) {
    //     if (is_prime[s][e]) return dp[s][e] = 0;
    //     if (dp[s][e] != INT_MAX) return dp[s][e];
    //     int res = INT_MAX;
    //     for (int i = s; i < e; i++) {
    //         res = min(res, rect(s, i, is_prime, dp) + rect(i + 1, e, is_prime, dp) + 1);
    //         if (res == 1) break;
    //     }
    //     return dp[s][e] = res;
    // }

    int minCut(string s) {
        vector<vector<bool>> is_prime(s.length(), vector<bool>(s.length(), true));
        int sz = s.size(); // 
        for (int i = sz - 1; i >= 0; i--) {
            for (int j = i + 1; j < sz; j++) {
                is_prime[i][j] = is_prime[i + 1][j - 1] && (s[i] == s[j]);
            }
        }
        vector<int> dp(sz, INT_MAX); dp[0] = 0;
        for (int i = 1; i < sz; i++) {
            if (is_prime[0][i]) {
                dp[i] = 0; continue;
            }
            for (int j = 0; j < i; j++) {
                if (is_prime[j + 1][i]) {
                    dp[i] = min(dp[i], dp[j] + 1);
                }
            }
        }
        return dp[sz - 1];
    }
};
// @lc code=end

